<?php

namespace Mogod\Core\Model;

/**
 * Коллекция моделей
 *
 * @author morph, goorus
 */
class ModelCollection implements \IteratorAggregate
{
	/**
	 * Итератор коллекции
	 *
	 * @var \Mogod\Core\Structure\Vector\VectorIteratorAbstract
	 */
	protected $iterator;

	/**
	 * Модели коллекции
	 *
	 * @var array of \Mogod\Core\Model\Model
	 */
	protected $models;

	/**
	 * Добавляем элемент в коллекцию
	 *
	 * @param \Mogod\Core\Model\Model $model
	 * @return \Mogod\Core\Model\ModelCollection
	 */
	public function add($model)
	{
		$this->models[] = $model;
		return $this;
	}

	/**
	 * Сбросить список моделей
	 */
	public function clear()
	{
		$this->models = array();
	}

	/**
	 * Получить количество моделей коллекции
	 *
	 * @return integer
	 */
	public function count()
	{
		return sizeof($this->models);
	}

	/**
	 * Получить вектор значений определенного поля моделей коллекции
	 *
	 * @param $field $column Имя поля
	 */
	public function field($field)
	{
		$result = array();
		if ($this->models) {
			foreach ($this->models as $model) {
				$result[] = $model->getField($field);
			}
		}
		return $result;
	}

	/**
	 * Фильтрует коллекцию по средствам фильтра
	 *
	 * @param \Mogod\Core\Structure\Vector\VectorFilterAbstract $filter
	 * @return \Mogod\Core\Model\ModelCollection
	 */
	public function filter($filter)
	{
		$this->models = $filter->filter($this->models);
		return $this;
	}

	/**
	 * Получить первый элемент коллекции
	 *
	 * @return \Mogod\Core\Model\Model
	 */
	public function first()
	{
		if ($this->models) {
			return reset($this->models);
		}
	}

	/**
	 * Получить текущий итератор коллекции
	 *
	 * @return \Mogod\Core\Structure\Vector\VectorIteratorAbstract
	 */
	public function getIterator ()
	{
		return $this->iterator;
	}

	/**
	 * Получить все модели коллекции
	 *
	 * @return array of \Mogod\Core\Model\Model
	 */
	public function getModels()
	{
		return $this->models;
	}

	/**
	 * Пуста ли коллекция?
	 *
	 * @return booleanv
	 */
	public function isEmpty()
	{
		return !$this->models || !sizeof($this->models);
	}

	/**
	 * Получить модель по индексу
	 *
	 * @param integer $index Индекс модели
	 * @return \Mogod\Core\Model\Model
	 */
	public function item($index)
	{
		return isset($this->models[$index]) ? $this->models[$index] : null;
	}

	/**
	 * Получить последний элемент коллекции моделей
	 *
	 * @return \Mogod\Core\Model\Model
	 */
	public function last()
	{
		if ($this->models) {
			return end($this->models);
		}
	}

	/**
	 * Пройтись по элементам коллекции
	 *
	 * @param \Mogod\Core\Structure\Vector\VectorWalkerAbstract $walker
	 * @return mixed
	 */
	public function map($walker)
	{
		return $walker->walk($this->models);
	}

	/**
	 * Присоединить к коллекции вектор моделей или модели другой коллекции
	 *
	 * @param mixed $models
	 */
	public function merge($models)
	{
		$models = is_array($models) ? $models : $models->getModels();
		$this->models = array_merge((array) $this->models, (array) $models);
	}

	/**
	 * Установить текущий итератор коллекции
	 *
	 * @param \Mogod\Core\Structure\Vector\VectorIteratorAbstract $iterator
	 * @return \Mogod\Core\Model\ModelCollection
	 */
	public function setIterator($iterator)
	{
		$this->iterator = $iterator->init($this->models);
		return $this;
	}

	/**
	 * Изменить модели коллекции
	 *
	 * @param array of \Mogod\Core\Model\Model $models
	 */
	public function setModels($models)
	{
		$this->models = $models;
	}
}